MFPanels / 1.0 / frame panels using float positioning.html
file last updated : 2023-07-13
<html>

<head>

    <style>
        body {
            margin:0;
            padding:0;
        }
        .container {
            width: 100%;
            height: calc(100vh - 3px);
        }
        .left {
            width:25%;
        }
        .center {
            width: 49%;
            overflow:hidden!important;
        }
        .right {
            width: 25%;
        }
        .left, .center, .right {
            float:left;
            height:100%;
            margin:0;
            overflow:auto;
        }

        .left, .centerTop, .centerBottom, .right {
            padding:10px;
            box-sizing: border-box;
        }

        .left {
            background-color: lightgray;
            overflow: auto;
        }

        .centerTop {
            background-color: green;
            height: 25%
        }

        .centerBottom {
            background-color: pink;
            height: 75%
        }

        .centerTop,
        .centerBottom {
            overflow: auto;
        }

        .right {
            background-color: lightblue;
        }

        .dragger-h {
            position: fixed;
            background-color: white;
            opacity:0;
            width: 8px;
            height:100%;
            cursor: col-resize;
            z-index: 2;
        }
        .dragger-v {
            position: fixed;
            background-color: white;
            opacity:0;
            width: 100%;
            height:8px;
            cursor: row-resize;
            z-index: 2;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="left resizable-e" style='width:30%'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.</div>
        <div class="center resizable-e" style='width:50%'>
            <div class="centerTop resizable-s" style="height:20%">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.</div>
            <div class="centerBottom" style="height:80%">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.</div>
        </div>
        <div class="right" style='width:20%'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.</div>
    </div>
    <script>
        var _paneldragger=null, _paneldragMax;
        function getUniqueID(prefix) {
            var n=1;
            while(document.getElementById(prefix+n)) n++;
            return prefix+n;
        }

        function doRepositionDividers() {
            if ( 1==2 ) {
                var panelClasses = ['resizable-e', 'resizable-s'];
                var done = [];
                for (var c = 0; c < panelClasses.length; c++) {
                    var panels = document.getElementsByClassName(panelClasses[c]);
                    for (var p = 0; p < panels.length; p++) {
                        var panel = panels[p];
                        if (panel.getAttribute('data-dragger')) {
                            var dragger = document.getElementById(panel.getAttribute('data-dragger'));
                            if (panelClasses[c] == 'resizable-e') {
                                dragger.style.left = panel.getBoundingClientRect().width = 'px';
                                dragger.style.height = panel.getBoundingClientRect().height = 'px';
                            }
                            else {
                                dragger.style.top = panel.getBoundingClientRect().top = 'px';
                                dragger.style.width = panel.getBoundingClientRect().width = 'px';
                            }
                        }
                    }
                }
            }

            var draggers=document.getElementsByClassName('paneldragger');
            for(var d=0;d<draggers.length;d++) {
                var panel=document.getElementById(draggers[d].getAttribute('data-elem'));
                if (/\bdragger-h\b/.test(draggers[d].classList)) {
                    draggers[d].style.top=(panel.getBoundingClientRect().top)+'px';
                    draggers[d].style.left=(panel.getBoundingClientRect().left+panel.getBoundingClientRect().width)+'px';
                    draggers[d].style.height=(panel.getBoundingClientRect().top+panel.getBoundingClientRect().height)+'px';
                }
                if (/\bdragger-v\b/.test(draggers[d].classList)) {
                    draggers[d].style.left=(panel.getBoundingClientRect().left)+'px';
                    draggers[d].style.top=(panel.getBoundingClientRect().top+panel.getBoundingClientRect().height)+'px';
                    draggers[d].style.width=(+panel.getBoundingClientRect().width)+'px';
                }
            }
        }


        window.addEventListener('resize', function() {
            doRepositionDividers();
        });


        var panels=document.getElementsByClassName('resizable-e');
        for(var i=0;i<panels.length; i++) {
            var panel = panels[i];
            if (!panel.id) panel.id = getUniqueID('left');
            var dragger = document.createElement('div');
            dragger.className = 'paneldragger dragger-h';

            dragger.style.left = (panel.getBoundingClientRect().left + panel.getBoundingClientRect().width) + 'px';
            dragger.style.top = panel.getBoundingClientRect().top + 'px';
            dragger.style.height = panel.getBoundingClientRect().height + 'px';
            dragger.setAttribute('data-elem', panel.id);
            dragger.id = getUniqueID('dragger');
            document.body.appendChild(dragger);
            panel.setAttribute('data-dragger',dragger.id);
        }


        var panels=document.getElementsByClassName('resizable-s');
        for(var i=0;i<panels.length; i++) {
            var panel = panels[i];
            if (!panel.id) panel.id = getUniqueID('top');
            var dragger = document.createElement('div');
            dragger.className = 'paneldragger dragger-v';

            dragger.style.top = (panel.getBoundingClientRect().top + panel.getBoundingClientRect().height) + 'px';
            dragger.style.left = panel.getBoundingClientRect().left + 'px';
            dragger.style.width = panel.getBoundingClientRect().width + 'px';
            dragger.setAttribute('data-elem', panel.id);
            dragger.id = getUniqueID('dragger');
            document.body.appendChild(dragger);
            panel.setAttribute('data-dragger',dragger.id);
        }


        var draggers=document.getElementsByClassName('paneldragger');
        for(var d=0;d<draggers.length;d++) {
            draggers[d].addEventListener('mousedown', function (e) {
                var dragger = e.target;
                if (/\bdragger-h\b/.test(dragger.classList)) {
                    _paneldragger = dragger;
                    var x = _paneldragger.getBoundingClientRect().left;
                    _paneldragger.setAttribute('data-startdrag', x);
                    _paneldragger.setAttribute('data-dragging', 1);

                    var leftElem = document.getElementById(_paneldragger.getAttribute('data-elem'));
                    var rightElem = leftElem.nextElementSibling;
                    _paneldragMax = rightElem.getBoundingClientRect().right;
                }
                if ( /\bdragger-v\b/.test(dragger.classList)) {
                    _paneldragger=dragger;
                    var y=_paneldragger.getBoundingClientRect().top;
                    _paneldragger.setAttribute('data-startdrag',y);
                    _paneldragger.setAttribute('data-dragging',1);

                    var topElem=document.getElementById(_paneldragger.getAttribute('data-elem'));
                    var bottomElem = topElem.nextElementSibling;
                    _paneldragMax = bottomElem.getBoundingClientRect().bottom;
                }
            });
        }


        window.addEventListener('mousemove', function(e) {
            if ( _paneldragger ) {
                if (/\bdragger-h\b/.test(_paneldragger.classList)) {
                    var x = parseInt(e.clientX);
                    if (x < _paneldragMax) {
                        if (_paneldragger.getAttribute('data-dragging') == 1 && x > 0) {
                            _paneldragger.setAttribute('data-startdrag', x);
                            _paneldragger.style.left = x + 'px';
                        }
                    }
                    var selection = window.getSelection();
                    if (selection.rangeCount > 0) selection.removeAllRanges();
                }
                if (/\bdragger-v\b/.test(_paneldragger.classList)) {
                    var y = parseInt(e.clientY);
                    if (y < _paneldragMax) {
                        if (_paneldragger.getAttribute('data-dragging') == 1 && y > 0) {
                            _paneldragger.setAttribute('data-startdrag', y);
                            _paneldragger.style.top = y + 'px';
                        }
                    }
                    var selection = window.getSelection();
                    if (selection.rangeCount > 0) selection.removeAllRanges();

                }
            }
        });


        window.addEventListener('mouseup', function(e) {
            if ( _paneldragger ) {
                if ( /\bdragger-h\b/.test(_paneldragger.classList) ) {
                    var leftElem = document.getElementById(_paneldragger.getAttribute('data-elem'));
                    var rightElem = leftElem.nextElementSibling;

                    _paneldragger.setAttribute('data-dragging', 0);

                    var ww = window.innerWidth;
                    var x0 = _paneldragger.getAttribute('data-startdrag');
                    var x = _paneldragger.getBoundingClientRect().left;
                    var left = leftElem.getBoundingClientRect().left;

                    //var w0 = leftElem.getBoundingClientRect().width;
                    if (/px/.test(leftElem.style.width)) console.error('PANEL ' + leftElem.id + ' width must be expressed in % and not px');
                    var w0 = parseFloat(leftElem.style.width.replace(/%/, ''));
                    var w1 = x - left;
                    var w1pct = (w1 * 100) / ww;

                    leftElem.style.width = w1pct + '%';
                    var rw = parseFloat(rightElem.style.width.replace(/%/, ''));
                    rightElem.style.width = (rw + (w0 - w1pct)) + '%';

                    _paneldragger = null;
                    doRepositionDividers();
                }
                else if ( /\bdragger-v\b/.test(_paneldragger.classList) ) {
                    // var topElem=document.getElementById(_paneldragger.getAttribute('data-elem'));
                    // _paneldragger.setAttribute('data-dragging',0);
                    // var y=_paneldragger.getBoundingClientRect().top;
                    // var top = topElem.getBoundingClientRect().top;
                    // var h0 = topElem.getBoundingClientRect().height;
                    // var h1 = y-top;
                    // var padding = parseInt(window.getComputedStyle(topElem).getPropertyValue('padding-top').replace(/px/,'')) + parseInt(window.getComputedStyle(topElem).getPropertyValue('padding-bottom').replace(/px/,''));
                    // topElem.style.height=parseInt(h1)+'px';
                    // var bottomElem = topElem.nextElementSibling;
                    // bottomElem.style.height = parseInt(bottomElem.getBoundingClientRect().height - (h1 - h0)) + 'px';
                    // _paneldragger=null;
                    // doRepositionDividers();

                    var topElem = document.getElementById(_paneldragger.getAttribute('data-elem'));
                    var bottomElem = topElem.nextElementSibling;

                    _paneldragger.setAttribute('data-dragging', 0);

                    var wh = window.innerHeight;
                    var y0 = _paneldragger.getAttribute('data-startdrag');
                    var y = _paneldragger.getBoundingClientRect().top;
                    var top = topElem.getBoundingClientRect().top;

                    if (/px/.test(topElem.style.height)) console.error('PANEL ' + topElem.id + ' height must be expressed in % and not px');
                    var h0 = parseFloat(topElem.style.height.replace(/%/, ''));
                    var h1 = y - top;
                    var h1pct = (h1 * 100) / wh;

                    topElem.style.height = h1pct + '%';
                    var bh = parseFloat(bottomElem.style.height.replace(/%/, ''));
                    bottomElem.style.height = (bh + (h0 - h1pct)) + '%';

                    _paneldragger = null;
                    doRepositionDividers();
                }
            }

        });


    </script>
</body>

</html>

About

License

Latest Release

Version 1.122024-05-08